package com.jiuye.filter;

import com.alibaba.fastjson.JSON;
import com.jiuye.common.BaseContext;
import com.jiuye.common.GlobalConstant;
import com.jiuye.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 登录过滤器
 *
 * @author likeWen
 * @since 2022/11/1 10:04
 */
@Slf4j
//urlPatterns这个注解中的属性，可以指定拦截的请求
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    /**
     * 未登录的提示信息
     */
    public static final String NOT_LOGIN = "NOTLOGIN";
    /**
     *   "/user/sendMsg" 发送验证码
     *   "/user/login" 用户登录
     * 放行的路径
     */
   public static final String[] URIS = new String[]{
            "/employee/login",
            "/employee/logout",
            "/backend/**",
            "/front/**",
            "/common/**",
            "/user/sendMsg",
            "/user/login",
            "/doc.html",
            "/webjars/**",
            "/swagger-resources",
            "/v2/api-docs"
    };

    //路径匹配器
    AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**
     * 所有指定的请求都会到达这里
     * 使用过滤器时，在处理完业务逻辑之后，是需要放行的
     */
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        log.info("已到达过滤器");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //1.获取本次请求的URL
        String requestURI = request.getRequestURI();
        //2.判断本次请求是否需要检验用户登录状态


        //如果不需要处理，直接放行
        for (String item : URIS) {
            //放行鉴权就是在做请求路径的匹配，如果要是符合我们在数组中定义的请求路径的话，就会放行
            //如果不匹配就走鉴权操作
            //匹配实际上就是在做字符串，对比的就是请求路径，以及我们在数据中定义的路径
            //匹配操作，成功会返会true
            //第一个参数是匹配的路径，第二个参数是请求路径
            boolean match = antPathMatcher.match(item, requestURI);
            //匹配成功 match==true
            if (match) {
                //放行操作
                filterChain.doFilter(request, response);
                return;
            }
        }
        //4.判断登录状态，如果已经登陆，则放行
        //由controller代码得知，session中存放的id，所以更改为Long属性
        Long employee = (Long) request.getSession().getAttribute(GlobalConstant.EMPLOYEE_ID);
        //如果不是空，就代表已经登录
        if (employee != null){
            //已登录，放行
            //存入threadLocal
            BaseContext.setCurrentUserId(employee);
            filterChain.doFilter(request,response);
            return;
        }
        //兼容移动端用户
        Long mobileId = (Long) request.getSession().getAttribute(GlobalConstant.MOBILE_ID);
        //如果不是空，就代表已经登录
        if (mobileId != null){
            //已登录，放行
            //存入threadLocal
            BaseContext.setCurrentUserId(mobileId);
            filterChain.doFilter(request,response);
            return;
        }
        //5.如果未登录，则返回未登录结果
        // ctrl + alt +c
        // 提前字符串变为常量的快捷键
        R<String> notlogin = R.error(NOT_LOGIN);
        response.getWriter().write(JSON.toJSONString(notlogin));
    }

}
